home *** CD-ROM | disk | FTP | other *** search
/ ASME's Mechanical Engine…ing Toolkit 1997 December / ASME's Mechanical Engineering Toolkit 1997 December.iso / c_lang / turcbook.lzh / TWINDOW.C < prev    next >
Text File  |  1988-01-10  |  14KB  |  670 lines

  1. /* -------------pg 73-------- twindow.c ------------------------ */
  2.  
  3. #include <stdio.h>
  4. #include <ctype.h>
  5. #include <stdarg.h>
  6. #include <dos.h>
  7. #include <alloc.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "twindow.h"
  11. #include "keys.h"
  12.  
  13. #define TABS       4
  14. #define SCRNHT    25
  15. #define SCRNWIDTH 80
  16. #define ON        1
  17. #define OFF       0
  18. #define ERROR     -1
  19.  
  20. redraw(WINDOW *wnd);
  21. wframe(WINDOW *wnd);
  22. dtitle(WINDOW *wnd);
  23. int *waddr(WINDOW *wnd,int x,int y);
  24. int dget(WINDOW *wnd,int x,int y);
  25. vswap(WINDOW *wnd);
  26. vsave(WINDOW *wnd);
  27. vrstr(WINDOW *wnd);
  28. add_list(WINDOW *wnd);
  29. beg_list(WINDOW *wnd);
  30. remove_list(WINDOW *wnd);
  31. insert_line(WINDOW *w1,WINDOW *w2);
  32. verify_wnd(WINDOW **w1);
  33.  
  34. struct {
  35.    int nw,ne,se,sw,side,line;
  36. } wcs[] = {
  37.    {218,191,217,192,179,196},
  38.    {201,187,188,200,186,205},
  39.    {214,183,189,211,186,196},
  40.    {213,184,190,212,179,205},
  41.    {194,194,217,192,176,196}
  42. };
  43.  
  44. WINDOW *listhead = NULL;
  45. WINDOW *listtail = NULL;
  46. int VSG;
  47.  
  48.  
  49. /* --------- establish a new window --------------- */
  50. WINDOW *establish_window(x,y,h,w)
  51. {
  52.   WINDOW *wnd;
  53.  
  54.   VSG = (vmode() == 7 ? 0xb000 : 0xb800);
  55.   if ((wnd = (WINDOW *)malloc(sizeof(WINDOW))) == NULL)
  56.     return NULL;
  57.   WTITLE = "";
  58.   HEIGHT = min(h,SCRNHT);
  59.   WIDTH = min(w,SCRNWIDTH);
  60.   COL = max(0,min(x,SCRNWIDTH-WIDTH));
  61.   ROW = max(0,min(y,SCRNHT-HEIGHT));
  62.   WCURS  = 0;
  63.   SCROLL = 0;
  64.   SELECT = 1;
  65.   BTYPE  = 0;
  66.   VISIBLE = HIDDEN = 0;
  67.   PREV = NEXT = NULL;
  68.   FHEAD = FTAIL = NULL;
  69.   WBORDER=WNORMAL=PNORMAL=WTITLEC=clr(BLACK,WHITE,BRIGHT);
  70.   WACCENT=clr(WHITE,BLACK,DIM);
  71.  
  72.   if((SAV=malloc(WIDTH*HEIGHT*2)) == (char *) 0)
  73.     return NULL;
  74.   add_list(wnd);
  75.  
  76. #ifndef FASTWINDOWS
  77.   clear_window(wnd);
  78.   wframe(wnd);
  79. #endif
  80.   return wnd;
  81. }
  82.  
  83.  
  84. /* ----------- set the window's border ------------------------- */
  85. void set_border(WINDOW *wnd, int btype)
  86. {
  87.   if(verify_wnd(&wnd)) {
  88.       BTYPE = btype;
  89.         redraw(wnd);
  90.         }
  91. }
  92.  
  93.  
  94. /* ------------ set colors ------------------------------------ */
  95. void set_colors(WINDOW *wnd,int area,int bg,int fg,int inten)
  96. {
  97.   if (vmode() == 7) {
  98.       if (bg!=WHITE && bg!=BLACK)
  99.              return;
  100.         if (bg!=WHITE && fg!=BLACK)
  101.              return;
  102.         }
  103.   if (verify_wnd(&wnd)) {
  104.         if(area==ALL)
  105.             while(area)
  106.                WCOLOR[--area]=clr(bg,fg,inten);
  107.         else
  108.             WCOLOR[area]=clr(bg,fg,inten);
  109.         redraw(wnd);
  110.         }
  111.   }
  112.  
  113.  
  114.  
  115.  
  116. /* -------------- set the intensity of a window ------------------ */
  117. void set_intensity(WINDOW *wnd, int inten)
  118. {
  119.   int area=ALL;
  120.  
  121.   if (verify_wnd(&wnd)) {
  122.      while(area) {
  123.          WCOLOR[--area] &= ~BRIGHT;
  124.          WCOLOR[area] |= inten;
  125.          }
  126.      redraw(wnd);
  127.      }
  128. }
  129.  
  130.  
  131.  
  132. /* -------------------- set title ----------------------------- */
  133. void set_title(WINDOW *wnd, char *title)
  134. {
  135.   if (verify_wnd(&wnd)) {
  136.      WTITLE = title;
  137.      redraw(wnd);
  138.      }
  139. }
  140.  
  141.  
  142. /* ------------- redraw a window -------------------------------- */
  143. static redraw(WINDOW *wnd)
  144. {
  145. #ifndef FASTWINDOWS
  146.   int x,y,chat,atr;
  147.  
  148.   for (y=1;y<HEIGHT-1;y++)
  149.       for(x=1;x<WIDTH-1;x++) {
  150.         chat = dget(wnd,x,y);
  151.         atr  = (((chat>>8)&255) == PNORMAL ? WNORMAL : WACCENT);
  152.         displ(wnd,x,y,chat&255,atr);
  153.       }
  154.       wframe(wnd);
  155. #endif
  156.   PNORMAL = WNORMAL;
  157. }
  158.  
  159.  
  160.  
  161. /* ------------------ display an established window ----------------- */
  162. void display_window(WINDOW *wnd)
  163. {
  164.   if(verify_wnd(&wnd) && !VISIBLE) {
  165.      VISIBLE = 1;
  166. #ifdef FASTWINDOWS
  167.      if(HIDDEN) {
  168.         HIDDEN=0;
  169.         vrstr(wnd);
  170.      }
  171.      else {
  172.         vsave(wnd);
  173.         clear_window(wnd);
  174.         wframe(wnd);
  175.      }
  176. #else
  177.      vswap(wnd);
  178. #endif
  179.   }
  180. }
  181.  
  182.  
  183.  
  184. /* ------------------------ close all windows ------------------------ */
  185. void close_all()
  186. {
  187.   WINDOW *sav, *wnd = listtail;
  188.  
  189.   while(wnd) {
  190.      sav = PREV;
  191.      delete_window(wnd);
  192.      wnd = sav;
  193.      }
  194. }
  195.  
  196.  
  197.  
  198. /* ---------------- remove a window ---------------------------- */
  199. void delete_window(WINDOW *wnd)
  200. {
  201.   if (verify_wnd(&wnd)) {
  202.      hide_window(wnd);
  203.      free(SAV);
  204.      remove_list(wnd);
  205.      free(wnd);
  206.      }
  207. }
  208.  
  209.  
  210.  
  211. /* --------------------- hide a window ----------------------------- */
  212. void hide_window(WINDOW *wnd)
  213. {
  214.   if (verify_wnd(&wnd) && VISIBLE) {
  215. #ifndef FASTWINDOWS
  216.      vswap(wnd);
  217. #else
  218.      vrstr(wnd);
  219. #endif
  220.      HIDDEN  = 1;
  221.      VISIBLE = 0;
  222.      }
  223. }
  224.  
  225.  
  226.  
  227. #ifndef FASTWINDOWS
  228. /* ------------ reposition the window in its 3-axis plane ------------ */
  229. void repos_wnd(WINDOW *wnd, int x, int y, int z)
  230. {
  231.   WINDOW *twnd;
  232.   int x1,y1,chat;
  233.  
  234.   if(!verify_wnd(&wnd))
  235.      return;
  236.   twnd = establish_window(x+COL, y+ROW, HEIGHT, WIDTH);
  237.   twnd->_tl   = WTITLE;
  238.   twnd->btype = BTYPE;
  239.   twnd->wcolor[BORDER] = WBORDER;
  240.   twnd->wcolor[TITLE]  = WTITLEC;
  241.   twnd->wcolor[ACCENT] = WACCENT;
  242.   twnd->wcolor[NORMAL] = WNORMAL;
  243.   twnd->_wsp = SCROLL;
  244.   twnd->_cr  = WCURS;
  245.  
  246.   if (z!=1) {
  247.     remove_list(twnd);
  248.     if(z==0)
  249.       insert_list(twnd,wnd);
  250.     else
  251.       beg_list(twnd);
  252.   }
  253.   for( y1=0; y1<twnd->_wh; y1++)
  254.     for(x1=0;x1<twnd->_ww; x1++) {
  255.       chat = dget(wnd,x1,y1);
  256.       displ(twnd,x1,y1,chat&255,(chat>>8)&255);
  257.       }
  258.   twnd->_wv = 1;
  259.   vswap(twnd);
  260.   hide_window(wnd);
  261.   free(SAV);
  262.   remove_list(wnd);
  263.   *wnd = *twnd;
  264.   insert_list(wnd,twnd);
  265.   remove_list(twnd);
  266.   free(twnd);
  267. }
  268. #endif
  269.  
  270.  
  271.  
  272. /* ------------------- clear the window area --------------------- */
  273. void clear_window(WINDOW *wnd)
  274. {
  275.   register int x1, y1;
  276.  
  277.   if(verify_wnd(&wnd))
  278.     for (y1=1;y1<HEIGHT-1;y1++)
  279.       for(x1=1;x1<WIDTH-1;x1++)
  280.         displ(wnd,x1,y1,' ',WNORMAL);
  281. }
  282.  
  283.  
  284.  
  285. /* ---------------------- draw the window frame ------------------- */
  286. static wframe(WINDOW *wnd)
  287. {
  288.   register int x1,y1;
  289.  
  290.   if(!verify_wnd(&wnd))
  291.     return;
  292.   /* ------------ window title --------------- */
  293.   displ(wnd,0,0,NW,WBORDER);
  294.   dtitle(wnd);
  295.   displ(wnd,WIDTH-1,0,NE,WBORDER);
  296.   /* ------------ window sides --------------- */
  297.   for(y1=1;y1<HEIGHT-1;y1++) {
  298.     displ(wnd,0,y1,SIDE,WBORDER);
  299.     displ(wnd,WIDTH-1,y1,SIDE,WBORDER);
  300.   }
  301.   /* ------------ bottom of frame ------------ */
  302.   displ(wnd,0,y1,SW,WBORDER);
  303.   for( x1=1;x1<WIDTH-1;x1++)
  304.     displ(wnd,x1,y1,LINE,WBORDER);
  305.  displ(wnd,x1,y1,SE,WBORDER);
  306. }
  307.  
  308.  
  309.  
  310. /* ---------------- display the window title ----------------------- */
  311. static dtitle(WINDOW *wnd)
  312. {
  313.   int x1=1,i,ln;
  314.   char *s = WTITLE;
  315.  
  316.   if (!verify_wnd(&wnd))
  317.     return;
  318.   if (s) {
  319.     ln = strlen(s);
  320.     if(ln>WIDTH-2)
  321.       i=0;
  322.     else
  323.       i=((WIDTH-2-ln)/2);
  324.     if (i>0)
  325.       while(i--)
  326.          displ(wnd,x1++,0,LINE,WBORDER);
  327.     while (*s && x1 < WIDTH-1)
  328.       displ(wnd,x1++,0,*s++,WTITLEC);
  329.     }
  330.   while(x1<WIDTH-1)
  331.     displ(wnd,x1++,0,LINE,WBORDER);
  332. }
  333.  
  334.  
  335. /* --------------- window-oriented printf ------------------- */
  336. void wprintf(WINDOW *wnd, char *ln, ...)
  337. {
  338.   char dlin[100], *dl=dlin;
  339.  
  340.   if(verify_wnd( &wnd )) {
  341.     va_list ap;
  342.     va_start(ap,ln);
  343.     vsprintf(dlin,ln,ap);
  344.     va_end(ap);
  345.     while (*dl)
  346.         wputchar(wnd,*dl++);
  347.     }
  348. }
  349.  
  350.  
  351. /* ----------------- write a character to the window ---------------- */
  352. void wputchar(WINDOW *wnd, int c)
  353. {
  354.   if(!verify_wnd(&wnd))
  355.     return;
  356.   switch(c) {
  357.     case '\n':
  358.       if( SCROLL==HEIGHT-3)
  359.         scroll(wnd,UP);
  360.       else
  361.         SCROLL++;
  362.       WCURS=0;
  363.       break;
  364.     case '\t':
  365.       do displ(wnd,(WCURS++)+3,SCROLL+1,' ',WNORMAL);
  366.         while((WCURS%TABS) && (WCURS+1) < WIDTH-1);
  367.       break;
  368.     default:
  369.       if((WCURS+1) < WIDTH-1) {
  370.         displ(wnd,WCURS+1,SCROLL+1,c,WNORMAL);
  371.         WCURS++;
  372.         }
  373.       break;
  374.    }
  375. }
  376.  
  377.  
  378.  
  379. /* ----------- set window cursor ---------------------- */
  380. void wcursor(WINDOW *wnd, int x, int y)
  381. {
  382.   if(verify_wnd(&wnd) && x<WIDTH-1 && y<HEIGHT-1) {
  383.     WCURS=x;
  384.     SCROLL=y;
  385.     cursor(COL+x+1,ROW+y+1);
  386.     }
  387. }
  388.  
  389.  
  390. /* --------------- allow the user to make a window selection ---------- */
  391. int get_selection(WINDOW *wnd,int s, char *keys)
  392. {
  393.   int c=0,ky;
  394.   if(!verify_wnd(&wnd))
  395.     return 0;
  396.   SELECT = s;
  397.   while(c!=ESC && c!='\r' && c!=BS && c!=FWD) {
  398.     accent(wnd);
  399.     c=get_char();
  400.     deaccent(wnd);
  401.     switch(c)  {
  402.       case UP :       if (SELECT > 1)
  403.                          SELECT--;
  404.                       else
  405.                          SELECT = SCROLL+1;
  406.                       break;
  407.       case DN :       if (SELECT < SCROLL+1)
  408.                          SELECT++;
  409.                       else
  410.                          SELECT=1;
  411.                       break;
  412.       case '\r' :
  413.       case ESC  :
  414.       case FWD  :
  415.       case BS   :  break;
  416.       default  :      if(keys) {
  417.                           ky=0;
  418.                           while(*(keys+ky)) {
  419.                             if(*(keys+ky)==toupper(c) ||
  420.                                *(keys+ky)==tolower(c))
  421.                                  return ky+1;
  422.                              }
  423.                         }
  424.                         break;
  425.        }
  426.    }
  427.    return c=='\r' ? SELECT : c==ESC ? 0 : c;
  428. }
  429.  
  430.  
  431. union REGS rg;
  432. /* ------------------- scroll a window's contents up or down ----------- */
  433. void scroll(WINDOW *wnd, int dir)
  434. {
  435.   int row=HEIGHT-1,col,chat;
  436.  
  437.   if(!verify_wnd(&wnd))
  438.      return;
  439.   if(NEXT==NULL && HEIGHT > 3 && VISIBLE)
  440.     {
  441.     rg.h.ah = dir == UP ? 6 : 7;
  442.     rg.h.al = 1;
  443.     rg.h.bh = WNORMAL;
  444.     rg.h.cl = COL+1;
  445.     rg.h.ch = ROW+1;
  446.     rg.h.dl = COL+WIDTH-2;
  447.     rg.h.dh = ROW+HEIGHT-2;
  448.     int86(16,&rg,&rg);
  449.     return;
  450.     }
  451.   if(dir==UP)
  452.     {
  453.     for(row=2;row<HEIGHT-1;row++)
  454.       for(col=1;col<WIDTH-1;col++) {
  455.           chat=dget(wnd,col,row);
  456.         displ(wnd,col,row-1,chat&255,(chat>>8)&255);
  457.         }
  458.       for(col=1;col<WIDTH-1;col++)
  459.         displ(wnd,col,row-1,' ',WNORMAL);
  460.     }
  461.   else {
  462.     for(row=HEIGHT-2;row>1;--row)
  463.       for(col=1;col<WIDTH-1;col++) {
  464.         chat=dget(wnd,col,row);
  465.         displ(wnd,col,row+1,chat&255,(chat>>8)&255);
  466.         }
  467.       for(col=1;col<WIDTH-1;col++)
  468.         displ(wnd,col,row+1,' ',WNORMAL);
  469.       }
  470.     }
  471.  
  472.  
  473. #ifndef FASTWINDOWS
  474. /* ---- compute the address of a window's display character ----------- */
  475. static int *waddr(WINDOW *wnd,int x,int y)
  476. {
  477.   WINDOW *nxt = NEXT;
  478.   int *vp;
  479.  
  480.   if(!VISIBLE)
  481.     return(int *)(SAV+y*(WIDTH*2)+x*2);
  482.   x += COL;
  483.   y += ROW;
  484.   while(nxt) {
  485.     if(nxt->_wv)
  486.       if(x >= nxt->_wx && x<= nxt->_wx + nxt->_ww-1)
  487.         if(y >= nxt->_wy && y<= nxt->_wy + nxt->_wh-1) {
  488.           x -= nxt->_wx;
  489.           y -= nxt->_wy;
  490.           vp = (int *)((nxt->_ws)+y*(nxt->_ww*2)+x*2);
  491.           return vp;
  492.           }
  493.     nxt = nxt->_nx;
  494.     }
  495.   return NULL;
  496. }
  497.  
  498.  
  499.  
  500. /* ---------- display a character to a window ------------------- */
  501. void displ(WINDOW *wnd,int x, int y, int ch, int at)
  502. {
  503.   int *vp;
  504.   int vch = (ch&255)|(at<<8);
  505.  
  506.   if((vp=waddr(wnd,x,y)) != NULL)
  507.     *vp = vch;
  508.   else
  509.     vpoke(VSG,vad(x+COL,y+ROW),vch);
  510. }
  511.  
  512.  
  513. /* --------- get a displayed character from a window ------------------- */
  514. static int dget(WINDOW *wnd,int x,int y)
  515. {
  516.   int *vp;
  517.  
  518.   if((vp=waddr(wnd,x,y)) != NULL)
  519.     return *vp;
  520.   return vpeek(VSG,vad(x+COL,y+ROW));
  521. }
  522.  
  523.  
  524.  
  525. /* -------- swap the video image with the save buffer ---------------- */
  526. static vswap(WINDOW *wnd)
  527. {
  528.   int x,y,chat;
  529.   int *bf=(int *)SAV;
  530.  
  531.   for (y=0; y<HEIGHT; y++)
  532.     for(x=0; x<WIDTH;x++) {
  533.       chat = *bf;
  534.       *bf++ = dget(wnd,x,y);
  535.       displ(wnd,x,y,chat&255,(chat>>8)&255);
  536.     }
  537. }
  538.  
  539.  
  540. #else
  541. /* ------------- save video memory into the save buffer ------------ */
  542. static vsave(WINDOW *wnd)
  543. {
  544.   int x,y;
  545.   int *bf = (int *)SAV;
  546.  
  547.   for(y=0;y<HEIGHT;y++)
  548.     for(x=0;x<WIDTH;x++)
  549.       *bf++ = vpeek(VSG,vad(x+COL,y+ROW));
  550. }
  551.  
  552.  
  553. /* ------------ restore video memory from the save buffer ---------- */
  554. static vrstr(WINDOW *wnd)
  555. {
  556.   int x,y;
  557.   int *bf=(int *)SAV;
  558.  
  559.   for(y=0;y<HEIGHT;y++)
  560.     for(x=0;x<WIDTH;x++)
  561.       vpoke(VSG,vad(x+COL,y+ROW), *bf++);
  562. }
  563. #endif
  564.  
  565.  
  566.  
  567. /* --------------- (de)accent the line where SELECT points ----------- */
  568. void acline(WINDOW *wnd, int set)
  569. {
  570.   int x,ch;
  571.  
  572.   if(!verify_wnd(&wnd))
  573.     return;
  574.   for(x=1;x<WIDTH-1;x++) {
  575.     ch = dget(wnd,x,SELECT) & 255;
  576.     displ(wnd,x,SELECT,ch,set);
  577.   }
  578. }
  579.  
  580.  
  581. /* ----- add a window to the end of the linked list -------------------- */
  582. static add_list(WINDOW *wnd)
  583. {
  584.   if(listtail) {
  585.     PREV = listtail;
  586.     listtail->_nx = wnd;
  587.   }
  588.   listtail = wnd;
  589.   if(!listhead)
  590.     listhead = wnd;
  591. }
  592.  
  593.  
  594. /* ------------ add a window to the beginning of the list -------------- */
  595. static beg_list(WINDOW *wnd)
  596. {
  597.   if(listhead) {
  598.     NEXT = listhead;
  599.     listhead->_pv = wnd;
  600.   }
  601.   listhead = wnd;
  602.   if(!listtail)
  603.     listtail = wnd;
  604. }
  605.  
  606. /* ------------ remove a window from the list --------------------------- */
  607. static remove_list(WINDOW *wnd)
  608. {
  609.   if(NEXT)
  610.     NEXT->_pv = PREV;
  611.   if(PREV)
  612.     PREV->_nx = NEXT;
  613.   if(listhead == wnd)
  614.     listhead = NEXT;
  615.   if(listtail == wnd)
  616.     listtail = PREV;
  617.   NEXT = PREV = NULL;
  618. }
  619.  
  620. /* -------------- insert w1 after w2 ------------------------------------ */
  621. static insert_list(WINDOW *w1, WINDOW *w2)
  622. {
  623.   w1->_pv = w2;
  624.   w1->_nx = w2->_nx;
  625.   w2->_nx = w1;
  626.   if(w1->_nx == NULL)
  627.     listtail = w1;
  628.   else
  629.     w1->_nx->_pv = w1;
  630. }
  631.  
  632.  
  633. /* ------------- verify the presence of a window in the list ------------- */
  634. static verify_wnd(WINDOW **w1)
  635. {
  636.   WINDOW *wnd;
  637.  
  638.   if(*w1 == NULL)
  639.     *w1 = listtail;
  640.   else  {
  641.     wnd = listhead;
  642.     while( wnd != NULL ) {
  643.       if(*w1==wnd)
  644.         break;
  645.       wnd = NEXT;
  646.     }
  647.  }
  648.  return *w1 != NULL;
  649. }
  650.  
  651.  
  652. WINDOW *ewnd = NULL;
  653. /* ------------- error messages ------------- */
  654. void error_message(char *s)
  655. {
  656.   ewnd = establish_window(50,22,3,max(10,strlen(s)+2));
  657.   set_colors(ewnd,ALL,RED,YELLOW,BRIGHT);
  658.   set_title(ewnd, " ERROR! ");
  659.   display_window(ewnd);
  660.   wprintf(ewnd,s);
  661. /*  putchar(BELL);  */
  662. }
  663.  
  664. void clear_message()
  665. {
  666.   if(ewnd)
  667.     delete_window(ewnd);
  668.   ewnd=NULL;
  669. }
  670.